package service

import (
	"fmt"
	"github.com/kordar/k-means-server/src/pojo"
	"github.com/kordar/k-means-server/src/util"
	"log"
)

type KMeans struct {
	Data       []pojo.FeatureItem
	FeatureMap map[string][]float64
	Len        int
}

func (k KMeans) Run() map[pojo.FeatureItem][]pojo.FeatureItem {
	centers := make([]pojo.FeatureItem, 0, k.Len)
	groups := make(map[pojo.FeatureItem][]pojo.FeatureItem, k.Len)
	for i, datum := range k.Data {
		if i >= k.Len {
			break
		}
		url := datum.Url
		if k.FeatureMap[url] != nil {
			centers = append(centers, datum)
			groups[datum] = make([]pojo.FeatureItem, 0)
		}
	}
	return k.cluster(centers, groups)
}

func (k KMeans) cluster(centers []pojo.FeatureItem, groups map[pojo.FeatureItem][]pojo.FeatureItem) map[pojo.FeatureItem][]pojo.FeatureItem {
	log.Println(fmt.Sprintf("********centers=%d*******groups=%d****************", len(centers), len(groups)))
	// 计算样本到中心点的距离
	for _, datum := range k.Data {
		compare := util.GetMaxCompare(centers, datum, k.FeatureMap)
		groups[compare] = append(groups[compare], datum)
	}

	isGoon := false
	newCenters := make([]pojo.FeatureItem, 0)
	newGroups := make(map[pojo.FeatureItem][]pojo.FeatureItem)
	for key, group := range groups {
		// 新的中心点
		gg := util.GetCenterByCompareSum(group, k.FeatureMap)
		newCenters = append(newCenters, gg) // 新的中心点
		newGroups[gg] = make([]pojo.FeatureItem, 0)
		if gg.Id != key.Id {
			isGoon = true
		}
	}

	if isGoon {
		return k.cluster(newCenters, newGroups)
	}

	return groups

}
